using System;
using System.Collections;
using System.Data;
using BeeldBank.Business;
using BeeldBank.Business.Collection;


namespace BeeldBank.Business.Base
{
    /// <summary>
    /// Provides database independant methods for Word.
    /// </summary>
    public class WordBase : BusinessBase
    {
        internal WordBase(System.Data.DataRow row)
            : base(row)
        {
            this.OnPrepareForSave += new PrepareForSaveHandler(this.PrepareForSave);
        }

        public delegate void PrepareForSaveHandler();
        public event PrepareForSaveHandler OnPrepareForSave;

        #region property bool EnforceSave
        /// This property is used to indicate if the
        /// object in the save event should save, even
        /// if the object contents (marked as stereotype NOTENFORCESAVE) is not saved
        private bool _EnforceSave = false;
        public bool EnforceSave
        {
            get
            {
                return _EnforceSave;
            }
            set
            {
                _EnforceSave = value;
            }

        }
        #endregion

        #region PrepareForSaveBase()
        public void PrepareForSaveBase()
        {
            if (!this.PrepareForSaveFinished)
            {
                if (OnPrepareForSave != null)
                {
                    OnPrepareForSave();
                }
                this.CanLoad = false;
                // call prepareforsave on all dependant objects.
                if (this.WordItems != null)
                {
                    foreach (WordItem wordItem in this.WordItems)
                    {
                        wordItem.PrepareForSaveBase();
                    }
                }
                this.CanLoad = true;
                this.PrepareForSaveFinished = true;
            }
        }
        #endregion

        #region PrepareForSave()
        public virtual void PrepareForSave()
        {
        }
        #endregion

        #region PreSave()
        public virtual void PreSave()
        {
        }
        #endregion

        #region Save()
        public void Save()
        {
            bool IsSaveNeeded = ContentChanged();

            if (IsDirty)
            {
                if (this.State == BusinessState.New)
                {
                    BeeldBank.Data.Word.Insert(this._dataRow, _luw.Transaction);
                    if (this.WordItems != null)
                    {
                        foreach (WordItem wordItem in this.WordItems)
                        {
                            wordItem.WordId = this.Id;
                        }
                    }
                }

                if ((this.State == BusinessState.Changed) && (IsSaveNeeded))
                {
                    BeeldBank.Data.Word.Update(this._dataRow, _luw.Transaction);
                }

                if (this.State == BusinessState.Deleted)
                {
                    if (this.WordItems != null)
                    {
                        foreach (WordItem wordItem in this.WordItems)
                        {
                            wordItem.Save();
                        }
                    }
                    BeeldBank.Data.Word.Delete(this._dataRow, _luw.Transaction);

                }
                IsDirty = false;
            }
        }
        #endregion

        #region OldWord
        private Word _oldWord;
        public Word OldWord
        {
            get
            {
                if (_oldWord == null && this.State != BusinessState.New)
                {
                    // Create the new object in a completely separate luw,
                    // otherwise a reference the the current object is returned.
                    Luw luw = new Luw(this.Luw.UserName);
                    _oldWord = luw.NewWord(BeeldBank.Data.Word.Open(this.Id).Rows[0]);
                }
                return _oldWord;
            }
        }
        #endregion

        #region Id
        /// <summary>
        /// Primaire sleutel
        /// </summary>
        public int Id
        {
            get
            {
                return Convert.ToInt32(_dataRow["Id"]);
            }
            set
            {
                _dataRow["Id"] = value;
                this.IsDirty = true;
            }
        }
        public bool IdIsNull
        {
            get
            {
                return _dataRow["Id"] == Convert.DBNull;
            }
        }
        public void IdSetNull()
        {
            _dataRow["Id"] = Convert.DBNull;
            this.IsDirty = true;
        }
        #endregion

        #region Word
        /// <summary>
        /// Het woord waarop gezocht kan worden.
        /// </summary>
        public string Word
        {
            get
            {
                return Convert.ToString(_dataRow["Word"]);
            }
            set
            {
                _dataRow["Word"] = value;
                this.IsDirty = true;
            }
        }
        public bool WordIsNull
        {
            get
            {
                return _dataRow["Word"] == Convert.DBNull;
            }
        }
        public void WordSetNull()
        {
            _dataRow["Word"] = Convert.DBNull;
            this.IsDirty = true;
        }
        #endregion

        #region WordCorrection
        /// <summary>
        /// Het woord waarmee het originele woord gecorrigeerd moet worden.
        /// </summary>
        public string WordCorrection
        {
            get
            {
                return Convert.ToString(_dataRow["WordCorrection"]);
            }
            set
            {
                _dataRow["WordCorrection"] = value;
                this.IsDirty = true;
            }
        }
        public bool WordCorrectionIsNull
        {
            get
            {
                return _dataRow["WordCorrection"] == Convert.DBNull;
            }
        }
        public void WordCorrectionSetNull()
        {
            _dataRow["WordCorrection"] = Convert.DBNull;
            this.IsDirty = true;
        }
        #endregion

        #region WordAlternative
        /// <summary>
        /// Het woord dat als alternatief wordt toegevoegd aan het object met dit trefwoord.
        /// </summary>
        public string WordAlternative
        {
            get
            {
                return Convert.ToString(_dataRow["WordAlternative"]);
            }
            set
            {
                _dataRow["WordAlternative"] = value;
                this.IsDirty = true;
            }
        }
        public bool WordAlternativeIsNull
        {
            get
            {
                return _dataRow["WordAlternative"] == Convert.DBNull;
            }
        }
        public void WordAlternativeSetNull()
        {
            _dataRow["WordAlternative"] = Convert.DBNull;
            this.IsDirty = true;
        }
        #endregion

        #region CreatedAt
        public DateTime CreatedAt
        {
            get
            {
                return Convert.ToDateTime(_dataRow["CreatedAt"]);
            }
            set
            {
                _dataRow["CreatedAt"] = value;
                this.IsDirty = true;
            }
        }
        #endregion

        #region ModifiedAt
        public DateTime ModifiedAt
        {
            get
            {
                return Convert.ToDateTime(_dataRow["ModifiedAt"]);
            }
            set
            {
                _dataRow["ModifiedAt"] = value;
                this.IsDirty = true;
            }
        }
        #endregion

        #region WordItems
        private WordItemCollection _wordItems;
        public WordItemCollection WordItems
        {
            get
            {
                if (_wordItems == null && _luw.CanLoad && this.CanLoad && !IdIsNull)
                {
                    _wordItems = new WordItemCollection(_luw, BeeldBank.Data.WordItem.OpenFromWordId(Id));
                }
                if (_wordItems == null && _luw.CanLoad && this.CanLoad && IdIsNull)
                {
                    _wordItems = new WordItemCollection(_luw);
                }
                return _wordItems;
            }
        }
        #endregion

        #region ContentChanged
        /// <summary>
        /// ContentChanged
        /// This function checks whether the content of a record is changed, dependant on the "EnforceSave" 
        /// variable. If EnforceSave is false, all the fields which have not been marked "NOTENFORCINGSAVE" as
        /// a stereotype in the design are checked. The contents of the fields are checked against the old values
        /// if they are not equal,the result is true. If the contents are equal, the result is false.
        /// 
        /// If EnforceSave is true, the result is always true.
        /// </summary>
        /// <returns>boolean indicating whether the Content is Changed</returns>
        public bool ContentChanged()
        {
            // Change enforced by Class Variables
            if (this.EnforceSave) { return (true); }
            if (this.IdIsNull) { return (true); }

            // Change enforced by the attributes

            #region Id
            /// Id is excluded because it is the primary key
            #endregion

            #region Word

            if (this.WordIsNull != this.OldWord.WordIsNull) { return (true); }
            if (this.Word != this.OldWord.Word) { return (true); }

            #endregion

            #region WordCorrection

            if (this.WordCorrectionIsNull != this.OldWord.WordCorrectionIsNull) { return (true); }
            if (this.WordCorrection != this.OldWord.WordCorrection) { return (true); }

            #endregion

            #region WordAlternative

            if (this.WordAlternativeIsNull != this.OldWord.WordAlternativeIsNull) { return (true); }
            if (this.WordAlternative != this.OldWord.WordAlternative) { return (true); }

            #endregion

            return false;
        }
        #endregion

        #region WhereAmI
        /// <summary>
        /// Provides the WhereAmI display text for a Word with the specified id
        /// </summary>
        /// <param name="id">Id of the Word.</param>
        /// <return>>WhereAmI display text</returns>
        public static string WhereAmI(int id)
        {
            string whereAmI = "";
            if (id == 0)
            {
                whereAmI = "New Word";
            }
            else
            {
                DataTable table = BeeldBank.Data.Word.Show(id);

                whereAmI = whereAmI + table.Rows[0]["Word"].ToString();

            }
            return whereAmI;
        }
        #endregion

    }
}
